﻿//51. N 皇 后
//按照国际象棋的规则，皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。
//n 皇后问题 研究的是如何将 n 个皇后放置在 n×n 的棋盘上，并且使皇后彼此之间不能相互攻击。
//给你一个整数 n ，返回所有不同的 n 皇后问题 的解决方案。
//每一种解法包含一个不同的 n 皇后问题 的棋子放置方案，该方案中 'Q' 和 '.' 分别代表了皇后和空位。

class Solution {
public:
    vector<int> row, col, dig1, dig2;
    bool check(int row, int col, vector<string>& chessboard, int n)
    {
        int count = 0;
        // 检查列
        for (int i = 0; i < row; i++) { // 这是一个剪枝
            if (chessboard[i][col] == 'Q') {
                return false;
            }
        }
        // 检查 45度角是否有皇后
        for (int i = row - 1, j = col - 1; i >= 0 && j >= 0; i--, j--) {
            if (chessboard[i][j] == 'Q') {
                return false;
            }
        }
        // 检查 135度角是否有皇后
        for (int i = row - 1, j = col + 1; i >= 0 && j < n; i--, j++) {
            if (chessboard[i][j] == 'Q') {
                return false;
            }
        }
        return true;
    }

    void dfs(vector<vector<string>>& ans, vector<string>& board, int row, int n)
    {
        //递归出口
        if (row == n)
        {
            ans.push_back(board);
            return;
        }
        //递归
        for (int i = 0; i < n; i++)
        {
            int rc = row - i + n - 1;
            //判断是否合法
            if (check(row, i, board, n))
            {
                //合法
                board[row][i] = 'Q';
                //递归
                dfs(ans, board, row + 1, n);
                //回溯
                board[row][i] = '.';
            }
        }
    }
    vector<vector<string>> solveNQueens(int n)
    {
        vector<vector<string>>  ans;
        vector<string> board(n, string(n, '.'));
        dfs(ans, board, 0, n);
        return ans;
    }
};